热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

专栏|Zabbix使用JavaScript配置Webhook发送告警通知

Wanger | Zabbix开源社区签约专家Zabbix运维工程师,熟悉Zabbix开源监控系统的架构。乐于分享Zabbix运维经验,个人公众号“运维开发故事

Wanger | Zabbix开源社区签约专家

Zabbix运维工程师,熟悉Zabbix开源监控系统的架构。乐于分享Zabbix运维经验,个人公众号“运维开发故事”。

擅长领域:Zabbix基础设施运维以及Zabbix图形化展示。

背景

Zabbix从4.4开始支持使用自定义的Javascript代码来配置Webhook媒介类型实现故障报警通知,这又为用户提供了一种使用前端代码来进行报警通知的方式。相比于在后端配置告警脚本的好处是代码可维护性更强,支持媒介类型的导入导出,省去了后端调试代码的步骤,使Zabbix更加的开箱即用。本文介绍Webhook的媒介类型是怎么配置的。

实现原理

首先看官方文档有详细介绍,Zabbix官方提供了大量的webhook媒介类型,虽然很多我们都用不上,但是我们可以参考他们的代码实现,来照葫芦画瓢编写适合我们自己的webhook媒介类型。之前我本人也看了一点点Javascript的基础,但后来看官方编写的代码和文档的时候,发现其实并不需要有多好的Javascript基础,有些代码官方又直接封装了一下,可以拿过来直接用。实现原理简单来说就是通过传入参数到Javascript代码中,Javascript会构造http请求并将传入的参数作为请求的一部分发送出去。

Zabbix封装的Javascript对象

Zabbix官方为方便我们使用Javascript的预处理和使用Webhook的媒介类型,特意在上面封装了一些对象给我们使用,同样目的也是为了能够更好的开箱即用。主要封装了两个对象。

写入zabbix日志的对象

方法描述
Log(loglevel, message)按照日志级别将写入 Zabbix 日志,日志级别可参考配置文件


例如:

Zabbix.Log(3, "this is a log entry written with 'Warning' log level")

http请求对象

官方还对http请求进行了封装,可以很方便的构造http请求。
方法描述
AddHeader(name, value)添加HTTP报头字段。此字段用于所有后续请求,直到使用ClearHeader()方法清除为止
ClearHeader()清除 HTTP 标头。如果没有设置报头字段,且发送的数据是 json 格式,默认会将 Content-Type 设置为 application/json,否则设置为 text/plain。
GetHeaders()返回接收到的 HTTP 标头字段的对象。
Get(url, data)将HTTP GET请求发送到带有可选_data_的URL,并返回响应
Put(url, data)将HTTP PUT请求发送到带有可选data的URL,并返回响应
Post(url, data)将HTTP POST请求发送到带有可选_data_的URL,并返回响应
Delete(url, data)将HTTP DELETE请求发送到带有可选data的URL,并返回响应
Status()返回最后一个HTTP请求的状态码
SetProxy(proxy)设置HTTP代理为“proxy”值。如果该参数为空,则不使用代理
官方在这里提供了一个例子来介绍如何使用封装的对象。

try {
    Zabbix.Log(4, 'jira webhook script value='+value);
 
    var result = {
        'tags': {
            'endpoint''jira'
        }
    },
    params = JSON.parse(value),
    req = new CurlHttpRequest(),
    fields = {},
    resp;
 
    req.AddHeader('Content-Type: application/json');
    req.AddHeader('Authorization: Basic '+params.authentication);
 
    fields.summary = params.summary;
    fields.description = params.description;
    fields.project = {"key": params.project_key};
    fields.issuetype = {"id": params.issue_id};
    resp = req.Post('https://tsupport.zabbix.lan/rest/api/2/issue/',
        JSON.stringify({"fields": fields})
    );
 
    if (req.Status() != 201) {
        throw 'Response code: '+req.Status();
    }
 
    resp = JSON.parse(resp);
    result.tags.issue_id = resp.id;
    result.tags.issue_key = resp.key;
} catch (error) {
    Zabbix.Log(4, 'jira issue creation failed json : '+JSON.stringify({"fields": fields}));
    Zabbix.Log(4, 'jira issue creation failed : '+error);
 
    result = {};
}
 
return JSON.stringify(result);

配置Webhook

如果我们想用官方现有的webhook媒介类型,则可以从git仓库或者源码包中下载并导入现有的xml,如果官方的webhook不能满足我们的需求则可以自己手动创建一个。webhook媒体类型的具体参数
前文说过,webhook的原理就是通过传递参数,然后对参数进行校验之后构建http请求并发送,webhook默认包含几个常用变量(URL :
, HTTPProxy:, To:{ALERT.SENDTO}, Subject:{ALERT.SUBJECT}, Message:{ALERT.MESSAGE}),传入的参数也支持问题通知中支持的所有宏,也支持使用http代理。选中Process tags_,_会讲webhook返回的json属性值作为问题事件标签。选中事件菜单复选框,可以在事件发生时点击问题名称访问外部的地址。

Webhook开发指南

官方的webhook开发指南说明点击查看。

数据验证

整个数据验证过程可以分为两部分:输入数据验证和外部系统响应数据验证。输入数据验证包括
  • Webhook 配置或 Webhook 测试中使用的值无效。
  • 缺少网络钩子参数。webhook 代码应该验证所需的参数并确定必需的参数是否存在。
  • 宏是否被解析。
输入数据验证的所有错误消息都应包含有关问题原因的信息和解决方法
响应数据验证包括
与用户输入验证一样,响应数据验证应确保来自外部系统的响应采用预期格式。这包括以下验证:
  • 是否有响应并且没有 HTTP 错误。
  • 响应是否包含预期格式的数据(原始/JSON/XML/等)。
  • 响应是否包含所有必需的字段或数据。
  • 响应数据中有没有错误。

返回值

虽然没有要求返回特定值,但在定义 webhook 的响应时应使用以下方法之一:如果 webhook 不使用标记:建议返回一个通用字符串(例如,OK
)来表示执行成功。如果 webhook 使用标签(标记Process tags复选框):webhook 应始终返回一个 JSON 对象,其中至少包含一个空对象的标签:{tags: {}}

日志记录

Webhooks 应该使用 Zabbix 提供的日志记录功能来为用户存储调试信息。应满足以下日志记录要求:
  • 应提供调试级别信息。 这可用于找出 webhook 逻辑中错误的原因。
  • 不需要在更高级别创建日志条目,因为 Zabbix 服务器会自动在“警告”(3)级别记录失败的 webhooks。
  • 日志条目应以 WEBHOOK 名称为前缀。这样是为了区分 webhook 创建的日志与和Zabbix Server 日志文件中的其他日志。
  • 无需在 WEBHOOK 的每一步都创建日志条目。

编写自定义webhook媒介类型实现发送钉钉报警通知

之前的文章已经介绍过编写脚本实现飞书的报警通知,这次将以webhook的媒介类型发送钉钉报警为例为大家介绍编写自定义的webhook媒介。

创建钉钉机器人

首先在电脑端创建自定义机器人,安全设置使用自定义关键词。


完成设置,保存好webhook,https://oapi.dingtalk.com/robot/send?access_token=e5906a9b879fe615323bd9489f46334f5539d6a46f8e29c5740ba02c7ee90e84

创建自定义报警媒介

进入报警媒介类型,选择webhook媒介类型,参数只需要填告警信息,接收人,webhook地址就可以了,脚本为:

var Dingding = {
    params: {},
    proxynull,
    setParamsfunction (params{
        if (typeof params !== 'object') {
            return;
        }
        Dingding.params = params; 
    },
    requestfunction () {
        var data = {
          msgtype"markdown",
          markdown: {
            title"报警",
            text"## 通知:\n " + Dingding.params.Message,
          },
          at: {
            atUserIds: [Dingding.params.To],
            isAtAllfalse,
          },
        },
        response,
        url = Dingding.params.URL,
        request = new HttpRequest();

        request.addHeader('Content-Type: application/json');
        if (typeof Dingding.HTTPProxy !== 'undefined' && Dingding.HTTPProxy !== '') {
            request.setProxy(Dingding.HTTPProxy);
        }

        if (typeof data !== 'undefined') {
            data = JSON.stringify(data);
        }
        Zabbix.Log(4"[Dingding Webhook] message is: " + data);
        response = request.post(url, data);

        Zabbix.log(4'[ Dingding Webhook ] Received response with status code ' +
            request.getStatus() + '\n' + response);

        if (response !== null) {
            try {
                response = JSON.parse(response);
            }
            catch (error) {
                Zabbix.log(4'[ Dingding Webhook ] Failed to parse response received from Dingding');
                response = null;
            }
        }
        
        if (request.getStatus() !== 200 || response.errcode !== 0) {
            var message = 'Request failed with status code '+request.getStatus();

            if (response !== null && typeof response.errmsg !== 'undefined') {
                message += ': 'JSON.stringify(response.errmsg) ;
            }

            throw message + '. Check debug log for more information.';
        }

        return response;
    },
};

    
try {
    var params = JSON.parse(value);
    
    if (typeof params.URL !== 'undefined' 
         && typeof params.To !== 'undefined'
         && typeof params.Message !== 'undefined') {
           Zabbix.log(4'[ Dingding Webhook ] webhookURL "' + params.URL +
                            '" sendto "'+ params.To )+'"';
        } 
        else {
          throw 'Missing parameter. URL, message, to parameter is required'
        }
    if (params.HTTPProxy) {
        Dingding.proxy = params.HTTPProxy;
    } 
    Dingding.setParams(params);
    Dingding.request();
    return 'OK';
}catch (error) {
    Zabbix.log(3'[ Dingding Webhook ] ERROR: ' + error);
    throw 'Sending failed: ' + error;
}


之后点击媒介类型后面的测试,输入参数就可以进行验证编写的自定义报警类型是否有问题。


告警消息是支持markdown的,可以将消息模板改成Markdown格式,会更好看一点。



 Zabbix5.0认证培训



7月12-16日 上海场



【客户案例】华为、中移在线、光大银行分享等

【官方博文】5.4新功能及路线图、技巧难点等

【专家专栏】周松、张思德、wanger等

Zabbix开源社区

由Zabbix大中华区唯一总代理上海宏时数据系统有限公司建立并维护,旨在提供最新资讯、交流平台和技术支持。



推荐阅读
  • PHP GuzzleHttp 无法获取到返回结果 ... [详细]
  • nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 最近学习了数据挖掘常用的两种算法:FP-Growth和K-Means。现在把我的学习结果分享给大家。以下是本文的目录,大家可以根据需要跳过一些章节:1.FP-Grow ... [详细]
  • 1、安装插件即可在源码管理中看见svn的选项subversion2、源码管理中配置svn的工程地址  3、点击Credentials的【添加】配置svn的用户名密码,完成后选取即可 ... [详细]
  • iOS网络开发(7)大牛们的杰作AFNetworking
    本篇文章介绍传说中的 AFN框架的使用AFNetworking是iOS开发中最广泛使用的开源项目之一,是最活跃最有影响力的开源项目之一。    ... [详细]
  • crossorigin注解添加了解决不了跨域问题_CORS与@CrossOrigin详解
    1、跨域的基本概念a、跨域的解释要了解跨域,首先需要知晓浏览器的同源策略,简单的说就是两个请求协议、端口、主机都相同,则两个请求具有相同的 ... [详细]
  •   uni-app开发教程,uni-app实例教程  UNI-APP开发(仿饿)开发课程:进入学习  推荐(免费):uni-app开发教程  文章目录  简介,网 ... [详细]
  • Linux下安装grafana并且添加influxdb监控的方法
    这篇文章主要介绍了Linux下安装grafana并且添加influxdb监控的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值, ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdownElasticsearch:更新现有索引的映射和设置相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 缓存的重要性就不用再强调了,@OutputCache给我们提供了一种声明的方式(对应的还有编程的方式)来控制页面和用户控件的缓存策略,这是一种最简单直接的网站优化方式。还是先来过一遍@ ... [详细]
  • 一、过滤器1.1概述(1)过滤器(Filters)提供了一种执行文本转换的方法,比如说都转换成大写字母或者几乎 ... [详细]
  • IE下PHPiframe跨域导致session丢失问题的解决方法|一个登录页面,被别的网站用iframe嵌进去后,死活无法登录(只在IE中存在这种情况)。主要是session无 ... [详细]
  • 做好了项上,其中包含有一个上传的功能。在开发环境和测试环境运行、测试都没什么问题。也许是由于本地的局域网的问题,一切都运行的比较快,但把它发布到外网的服务器上去时。就特别的慢。上传小的文件还算比 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
author-avatar
Damon777
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有